#ifndef __WIZ_LOG_HPP__SHANHAOBO_19800429__
#define __WIZ_LOG_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"
#include "../../System/WizLock.hpp"
#include <fstream>

namespace Wiz
{
    namespace Log
    {
        struct Type
        {
            ::std::ofstream     m_OutStream;
            ::Wiz::Lock::Type   m_WriteLock;
            ::Wiz::String::Type   m_Prefix;

            Type()
            {

            }

            Type(::Wiz::String::In fn) : m_OutStream(fn.GetCStr(), std::ios::app) 
            {

            }

            Type(::Wiz::String::In fn, ::Wiz::String::In pf) : m_OutStream(fn.GetCStr(), std::ios::app), m_Prefix(pf) 
            {

            }

            ::Wiz::Void::Type SetPrefix(::Wiz::String::In pf)
            {
                this->m_Prefix = pf;
            }

            ::Wiz::Void::Type Open(::Wiz::String::In fn)
            {
                this->SafeClose();

                ::Wiz::WString::Type WPath;
                ::Wiz::MultiBytesStrToWCharStr(WPath, fn, "chs");

                m_OutStream.open(WPath.GetCStr(), ::std::ios::app);
            }

            ::Wiz::Void::Type SafeClose()
            {
                if (this->IsOpened())
                {
                    m_OutStream.close();
                }
            }

            ::Wiz::Bool::Type IsOpened()
            {
                return m_OutStream.is_open();
            }

            ::Wiz::Void::Type MakePrefix(::Wiz::Char::Ptr BuffPtr, ::Wiz::Size::In BuffSize)
            {
                time_t ltime;
                time(&ltime);
                tm nowtime;
                _localtime64_s(&nowtime, &ltime);

                strftime(BuffPtr, BuffSize, "%Y-%m-%d %H-%M-%S", &nowtime);

                ::Wiz::Size::Type BSZ = strlen(BuffPtr);

                if (m_Prefix.Size() > 0)
                {
                    sprintf_s(BuffPtr + BSZ, BuffSize - BSZ, "[%s]", m_Prefix.GetCStr());
                }
                else
                {
                    sprintf_s(BuffPtr + BSZ, BuffSize - BSZ, ":");
                }
            }

            ::Wiz::Void::Type WIZ_CDECL Add(::Wiz::Char::FixedConstPtr Fmt, ...)
            {
                va_list va_alist;
                va_start (va_alist, Fmt);
                this->Add(Fmt, va_alist);
                va_end (va_alist);
            }

            ::Wiz::Void::Type WIZ_CDECL Add(::Wiz::Char::FixedConstPtr Fmt, va_list vl)
            {
                if(::Wiz::NotValidPtr(Fmt))
                {
                    return;
                }

                if(this->IsOpened())
                {
                    ::Wiz::ScopedLock::Type sl(this->m_WriteLock);

                    char logbuf[256];
                    this->MakePrefix(logbuf, 256);

                    sprintf_s(logbuf + strlen(logbuf), sizeof(logbuf) - strlen(logbuf), ":");

                    _vsnprintf(logbuf + strlen(logbuf), sizeof(logbuf) - strlen(logbuf), Fmt, vl);

                    m_OutStream << logbuf << ::std::endl;
                }
            }
        };
    } /// end of namespace Log
} /// end of namespace Wiz

#endif /*__WIZ_LOG_HPP__SHANHAOBO_19800429__*/
